#pragma once

#include <windows.h>

class Thread
{
	static DWORD WINAPI ThreadFunc(LPVOID pv)
	{
		try
		{
			(reinterpret_cast<Thread *>(pv))->run();
		}
		catch(...)
		{
		}
		return 0;
	}

public:
	typedef DWORD ThreadId;

	Thread()
  : bTerminated(false)
	{
    LockMutex = ::CreateMutex(NULL, FALSE, "MutexToPreventMultipleExecution");
	}
	virtual ~Thread()
	{
	}
	static ThreadId getThreadId()
	{
		return ::GetCurrentThreadId();
	}
	static void sleep(long milliseconds=1000)
	{
		::Sleep(milliseconds);
	}
	ThreadId start()
	{
		ThreadId id;
		::CreateThread(NULL, 0, ThreadFunc, this, 0, &id);
		return id;
	}
  bool waitForLock() 
  { 
    /*DWORD dwWaitResult =*/ ::WaitForSingleObject(LockMutex, INFINITE);
    return true;
  }
  void releaseLock() 
  {
    ::ReleaseMutex(LockMutex);
  }
  void terminate() { bTerminated = true; }
  bool isTerminated() { return bTerminated; }
	virtual void run() = 0;

protected:
  bool bTerminated;
  HANDLE LockMutex;
};
